package pers.yaoliguo.bms.realm;

import java.util.Collection;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;

import pers.yaoliguo.bms.entity.SysMenu;
import pers.yaoliguo.bms.entity.SysRoleMenuKey;
import pers.yaoliguo.bms.entity.SysUser;
import pers.yaoliguo.bms.service.ISysMenuRoleService;
import pers.yaoliguo.bms.service.ISysUserService;
import pers.yaoliguo.bms.service.impl.SysMenuService;
import pers.yaoliguo.bms.uitl.EhcacheUtil;
import pers.yaoliguo.bms.uitl.Global;
import pers.yaoliguo.bms.uitl.StringHelper;

/**
 * @ClassName:       ShiroDbRealm
 * @Description:    TODO
 * @author:            yao
 * @date:            2017年6月24日        下午6:16:01
 */
public class ShiroDbRealm extends AuthorizingRealm{

	@Autowired
	ISysUserService sysUserService;
	
	@Autowired
	ISysMenuRoleService sysMenuRoleService;
	
	@Autowired
	SysMenuService sysMenuService;
	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		
		//获取当前登录的用户名,等价于(String)principals.fromRealm(this.getName()).iterator().next()
		String account = (String)super.getAvailablePrincipal(principals);
		SysUser user = new SysUser();
		user.setAccount(account);
		user.setDel(false);
		List<SysUser> list = sysUserService.selectAll(user);
		if(list.size() == 0){
			throw new AuthenticationException("用户不存在。");
		}
		//从用户表中获取到角色id
		String roleId = list.get(0).getRoleId();
		SysRoleMenuKey roleMenu = new SysRoleMenuKey();
		roleMenu.setRoleId(roleId);
		//根据角色id去查该角色所有的菜单
		List<SysRoleMenuKey> roleMenuList= sysMenuRoleService.getrolemenus(roleMenu);
		//该用户的菜单
		List<SysMenu> menuList = sysMenuService.selectByIds(roleMenuList);
		//将菜单放入缓存中
		EhcacheUtil.getInstance().put(EhcacheUtil.MENU_CACHE, account, menuList);
		
		SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
		//将菜单的url作为权限编码，用来搜权
		for (SysMenu sysMenu : menuList) {
			if(!StringHelper.isNullOrEmpty(sysMenu.getUrl()))
			{
				simpleAuthorInfo.addStringPermission(sysMenu.getUrl());
			}
		}
		
		return simpleAuthorInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		
		//获取基于用户名和密码的令牌  
        //实际上这个authcToken是从LoginController里面currentUser.login(token)传过来的
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String account = token.getUsername();
		SysUser user = new SysUser();
		
		user.setAccount(account);
		user.setDel(false);
		List<SysUser> list = sysUserService.selectAll(user);
		AuthenticationInfo authcInfo =  null;
		if(list.size() > 0){
			//进行认证，将正确数据给shiro处理
			authcInfo = new SimpleAuthenticationInfo(list.get(0).getAccount(), list.get(0).getPassword(),this.getName());
			//清除之前的授权缓存，每次登录都重新授权
			super.clearCachedAuthorizationInfo(authcInfo.getPrincipals());
			SecurityUtils.getSubject().getSession().setAttribute(Global.LOGIN_USER_KEY, list.get(0));
			
		}else{
			throw new AuthenticationException("用户不存在！");
		}
		
		
		
		return authcInfo;
	}

}
